package cn.wolfcode;

import cn.wolfcode.controller.UserInfoController;
import cn.wolfcode.interceptor.CheckLoginInterceptor;
import cn.wolfcode.resolver.UserInfoArgumentResolver;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * @Description: 启动类, 实现WebMvcConfigurer相当于MVC.xml
 * @Author: 伍家钰
 * @Date: 2020/8/7 16:29
 * @Version: 1.0
 */
@SpringBootApplication
public class App implements WebMvcConfigurer {

    /**
     * 创建用户参数解析器对象交给Spring容器管理
     *
     * @return
     */
    @Bean
    public UserInfoArgumentResolver userInfoArgumentResolver() {
        return new UserInfoArgumentResolver();
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        // 将自定义的参数解析器加入进Spring的参数解析器集合中
        resolvers.add(userInfoArgumentResolver());
    }

    /**
     * 创建拦截器对象,交给SpringBoot管理
     *
     * @return :返回拦截器对象
     */
    @Bean
    public CheckLoginInterceptor checkLoginInterceptor() {
        return new CheckLoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册登入拦截器,同时对手机号验证,验证码验证,注册,及登入等操作进行放行
        registry.addInterceptor(checkLoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/users/checkPhone"
        ).excludePathPatterns("/users/sendVerifyCode").excludePathPatterns("/users/regist").excludePathPatterns(
                "/users/login");
    }

    /**
     * 配置跨域访问
     */
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            //重写父类提供的跨域请求处理的接口
            public void addCorsMappings(CorsRegistry registry) {
                //添加映射路径
                registry.addMapping("/**")
                        //放行哪些原始域
                        .allowedOrigins("*")
                        //是否发送Cookie信息
                        .allowCredentials(true)
                        //放行哪些原始域(请求方式)
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                        //放行哪些原始域(头部信息)
                        .allowedHeaders("*")
                        //暴露哪些头部信息（因为跨域访问默认不能获取全部头部信息）
                        .exposedHeaders("Header1", "Header2");
            }
        };
    }


    /**
     * mongodb 去除_class属性
     *
     * @param factory
     * @param context
     * @param beanFactory
     * @return
     */
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context,
                                                       BeanFactory beanFactory) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        try {
            mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // Don't save _class to mongo
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
